package com.xsg.printer.core.conditions;
import com.xsg.printer.core.enums.AlignEnum;
import com.xsg.printer.core.enums.FloatAlignEnum;
import com.xsg.printer.core.model.XsgMargin;

import com.xsg.printer.core.enums.ElementTypeEnum;
import com.xsg.printer.core.model.*;

import java.util.ArrayList;
import java.util.List;

public class ElementConfig {

    private List<XsgElement> elements;

    public ElementConfig(List<XsgElement> elements) {
        this.elements = elements;
    }

    public List<XsgElement> get() {
        return elements;
    }

    public static AddElement builder() {
        return new ElementConfigBuilder();
    }

    public interface AddElement {

        AddElement text(String name, int width, int height, AlignEnum alignEnum, XsgMargin margin, XsgFont font);

        default AddElement text(String name, int width, int height, AlignEnum alignEnum, XsgFont font) {
            return text(name, width, height, alignEnum, XsgMargin.defaultMargin(), font);
        }

        default AddElement text(String name, int width, int height, XsgMargin margin, XsgFont font) {
            return text(name, width, height, AlignEnum.TOP_LEFT, margin, font);
        }

        default AddElement text(String name, int width, int height, XsgFont font) {
            return text(name, width, height, AlignEnum.TOP_LEFT, XsgMargin.defaultMargin(), font);
        }

        default AddElement text(String name, int width, int height, XsgMargin margin) {
            return text(name, width, height, AlignEnum.TOP_LEFT, margin, XsgFont.defaultFont());
        }

        default AddElement text(String name, int width, int height, AlignEnum alignEnum) {
            return text(name, width, height, alignEnum, XsgMargin.defaultMargin(), XsgFont.defaultFont());
        }

        default AddElement text(String name, int width, int height, AlignEnum alignEnum, XsgMargin margin) {
            return text(name, width, height, alignEnum, margin, XsgFont.defaultFont());
        }

        default AddElement text(String name, int width, int height) {
            return text(name, width, height, XsgFont.defaultFont());
        }

        AddElement qrCode(String name, int width, int height, AlignEnum alignEnum, XsgMargin margin);

        default AddElement qrCode(String name, int width, int height, XsgMargin margin) {
            return qrCode(name, width, height, AlignEnum.TOP_LEFT, margin);
        }

        default AddElement qrCode(String name, int width, int height, AlignEnum alignEnum) {
            return qrCode(name, width, height, alignEnum, XsgMargin.defaultMargin());
        }

        default AddElement qrCode(String name, int width, int height) {
            return qrCode(name, width, height, XsgMargin.defaultMargin());
        }

        AddElement barCode(String name, int width, int height, AlignEnum alignEnum, XsgMargin margin);

        default AddElement barCode(String name, int width, int height, XsgMargin margin) {
            return barCode(name, width, height, AlignEnum.TOP_LEFT, margin);
        }

        default AddElement barCode(String name, int width, int height, AlignEnum alignEnum) {
            return barCode(name, width, height, alignEnum, XsgMargin.defaultMargin());
        }

        default AddElement barCode(String name, int width, int height) {
            return barCode(name, width, height, XsgMargin.defaultMargin());
        }

        AddElement image(String name, int width, int height, int localOrRemote, AlignEnum alignEnum, XsgMargin margin);

        default AddElement image(String name, int width, int height, AlignEnum alignEnum, XsgMargin margin) {
            return image(name, width, height, 0, alignEnum, margin);
        }
        default AddElement image(String name, int width, int height, XsgMargin margin) {
            return image(name, width, height, AlignEnum.TOP_LEFT, margin);
        }

        default AddElement image(String name, int width, int height, AlignEnum alignEnum) {
            return image(name, width, height, 0,alignEnum, XsgMargin.defaultMargin());
        }

        default AddElement image(String name, int width, int height) {
            return image(name, width, height, XsgMargin.defaultMargin());
        }

        default AddElement imageR(String name, int width, int height, XsgMargin margin) {
            return image(name, width, height, 1, AlignEnum.TOP_LEFT, margin);
        }

        default AddElement imageR(String name, int width, int height, AlignEnum alignEnum) {
            return image(name, width, height, 1,alignEnum, XsgMargin.defaultMargin());
        }

        default AddElement imageR(String name, int width, int height) {
            return image(name, width, height, XsgMargin.defaultMargin());
        }

        AddElement circle(String name, int width, int height, AlignEnum alignEnum, XsgMargin margin, XsgFont font);

        default AddElement circle(String name, int width, int height, AlignEnum alignEnum, XsgFont font) {
            return circle(name, width, height, alignEnum, XsgMargin.defaultMargin(), font);
        }

        default AddElement circle(String name, int width, int height, XsgMargin margin, XsgFont font) {
            return circle(name, width, height, AlignEnum.TOP_LEFT, margin, font);
        }

        default AddElement circle(String name, int width, int height, XsgFont font) {
            return circle(name, width, height, AlignEnum.TOP_LEFT, XsgMargin.defaultMargin(), font);
        }

        default AddElement circle(String name, int width, int height, XsgMargin margin) {
            return circle(name, width, height, AlignEnum.TOP_LEFT, margin, XsgFont.defaultFont());
        }

        default AddElement circle(String name, int width, int height, AlignEnum alignEnum) {
            return circle(name, width, height, alignEnum, XsgMargin.defaultMargin(), XsgFont.defaultFont());
        }

        default AddElement circle(String name, int width, int height, AlignEnum alignEnum, XsgMargin margin) {
            return circle(name, width, height, alignEnum, margin, XsgFont.defaultFont());
        }

        default AddElement circle(String name, int width, int height) {
            return circle(name, width, height, XsgFont.defaultFont());
        }

        AddElement sheet(String name, int width, int height, XsgSheet sheet, AlignEnum alignEnum, XsgMargin margin, XsgFont font);

        default AddElement sheet(String name, int width, int height, XsgSheet sheet, AlignEnum alignEnum, XsgFont font) {
            return sheet(name, width, height, sheet, alignEnum, XsgMargin.defaultMargin(), font);
        }

        default AddElement sheet(String name, int width, int height, XsgSheet sheet, XsgMargin margin, XsgFont font) {
            return sheet(name, width, height, sheet, AlignEnum.TOP_LEFT, margin, font);
        }

        default AddElement sheet(String name, int width, int height, XsgSheet sheet, XsgFont font) {
            return sheet(name, width, height, sheet, AlignEnum.TOP_LEFT, XsgMargin.defaultMargin(), font);
        }

        default AddElement sheet(String name, int width, int height, XsgSheet sheet, XsgMargin margin) {
            return sheet(name, width, height, sheet, AlignEnum.TOP_LEFT, margin, XsgFont.defaultFont());
        }

        default AddElement sheet(String name, int width, int height, XsgSheet sheet, AlignEnum alignEnum) {
            return sheet(name, width, height, sheet, alignEnum, XsgMargin.defaultMargin(), XsgFont.defaultFont());
        }

        default AddElement sheet(String name, int width, int height, XsgSheet sheet, AlignEnum alignEnum, XsgMargin margin) {
            return sheet(name, width, height, sheet, alignEnum, margin, XsgFont.defaultFont());
        }

        default AddElement sheet(String name, int width, int height, XsgSheet sheet) {
            return sheet(name, width, height, sheet, XsgFont.defaultFont());
        }

        ElementConfig build();
    }

    public static class ElementConfigBuilder implements AddElement {

        private List<XsgElement> elements;

        public ElementConfigBuilder() {
            this.elements = new ArrayList<>();
        }

        @Override
        public AddElement text(String name, int width, int height, AlignEnum alignEnum, XsgMargin margin, XsgFont font) {
            XsgElementText textElement = new XsgElementText();
            textElement.setWidth(width);
            textElement.setHeight(height);
            textElement.setFont(font);
            textElement.setType(ElementTypeEnum.TEXT.getType());
            textElement.setName(name);
            textElement.setValue(name);
            textElement.setMargin(margin);
            textElement.setAlign(alignEnum.getCode());
            elements.add(textElement);
            return this;
        }

        @Override
        public AddElement qrCode(String name, int width, int height, AlignEnum alignEnum, XsgMargin margin) {
            XsgElementQrCode xsgElementQrCode = new XsgElementQrCode();
            xsgElementQrCode.setWidth(width);
            xsgElementQrCode.setHeight(height);
            xsgElementQrCode.setType(ElementTypeEnum.QR.getType());
            xsgElementQrCode.setName(name);
            xsgElementQrCode.setValue(name);
            xsgElementQrCode.setAlign(alignEnum.getCode());
            xsgElementQrCode.setMargin(margin);
            elements.add(xsgElementQrCode);
            return this;
        }

        @Override
        public AddElement barCode(String name, int width, int height, AlignEnum alignEnum, XsgMargin margin) {
            XsgElementBarCode xsgElementBarCode = new XsgElementBarCode();
            xsgElementBarCode.setWidth(width);
            xsgElementBarCode.setHeight(height);
            xsgElementBarCode.setType(ElementTypeEnum.BAR.getType());
            xsgElementBarCode.setName(name);
            xsgElementBarCode.setValue(name);
            xsgElementBarCode.setAlign(alignEnum.getCode());
            xsgElementBarCode.setMargin(margin);
            elements.add(xsgElementBarCode);
            return this;
        }

        @Override
        public AddElement image(String name, int width, int height, int localOrRemote, AlignEnum alignEnum, XsgMargin margin) {
            XsgElementImage xsgElementImage = new XsgElementImage();
            xsgElementImage.setWidth(width);
            xsgElementImage.setHeight(height);
            xsgElementImage.setType(ElementTypeEnum.IMAGE.getType());
            xsgElementImage.setName(name);
            xsgElementImage.setValue(name);
            xsgElementImage.setAlign(alignEnum.getCode());
            xsgElementImage.setMargin(margin);
            xsgElementImage.setLocalOrRemote(localOrRemote);
            elements.add(xsgElementImage);
            return this;
        }

        @Override
        public AddElement circle(String name, int width, int height, AlignEnum alignEnum, XsgMargin margin, XsgFont font) {
            XsgElementCircle xsgElementCircle = new XsgElementCircle();
            xsgElementCircle.setWidth(width);
            xsgElementCircle.setHeight(height);
            xsgElementCircle.setFont(font);
            xsgElementCircle.setType(ElementTypeEnum.CIRCLE.getType());
            xsgElementCircle.setName(name);
            xsgElementCircle.setValue(name);
            xsgElementCircle.setMargin(margin);
            xsgElementCircle.setAlign(alignEnum.getCode());
            elements.add(xsgElementCircle);
            return this;
        }

        @Override
        public AddElement sheet(String name, int width, int height, XsgSheet sheet, AlignEnum alignEnum, XsgMargin margin, XsgFont font) {
            XsgElementSheet xsgElementSheet = new XsgElementSheet();
            xsgElementSheet.setWidth(width);
            xsgElementSheet.setHeight(height);
            xsgElementSheet.setFont(font);
            xsgElementSheet.setType(ElementTypeEnum.SHEET.getType());
            xsgElementSheet.setName(name);
            xsgElementSheet.setMargin(margin);
            xsgElementSheet.setSheet(sheet);
            xsgElementSheet.setAlign(alignEnum.getCode());
            elements.add(xsgElementSheet);
            return this;
        }

        @Override
        public ElementConfig build() {
            return new ElementConfig(elements);
        }
    }
}
